/*
  Name: DeadProxyClientMessageLog.cpp
  Copyright:
  Author: 19/02/08 12:22
  Description: Stores all messages recved and sent by the client
*/

#include "DeadProxyClientMessageLog.h"
#include <wx/arrimpl.cpp> //this is needed for wxArrays, i dont know why lol
WX_DEFINE_OBJARRAY(ArrayOfMessages);
WX_DEFINE_OBJARRAY(ArrayOfChannelLogs);

////////////////////Message Begin
Message::Message(wxString * sender, wxString * text, int type)
{
    Type = type;
    wxDateTime TStamp;
    TStamp.SetToCurrent();
    Time = TStamp.FormatISOTime();
    Sender = *sender;
    delete sender;
    Text = *text;
    delete text;
    LogString.Empty();
    LogString.Append(Time);
    LogString.Append("      ");
    LogString.Append(Sender);
    LogString.Append("      ");
    LogString.Append(Text);
}

wxString * Message::GetString()
{
    wxString * Ret = new wxString(LogString);
    return Ret;
}
////////////////////Message End
////////////////////Channel Log Begin
ChannelLog::ChannelLog(wxString * ChanName, int chanid)
{
    mutex = new wxMutex;
    Messages = new ArrayOfMessages();
    ChannelName = *ChanName;
    channelId = chanid;
}

int ChannelLog::GetNewMessageCount()
{
    return NewMessages;
}

void ChannelLog::ResetMessageCount()
{
    NewMessages = 0;
}

wxString * ChannelLog::AddMessage(wxString * sender, wxString * text, int type)
{
    Message * NewMessage = new Message(sender, text, type);
    mutex->Lock();
    Messages->Add(NewMessage);
    mutex->Unlock();
    return NewMessage->GetString();
}

wxArrayString * ChannelLog::GetMessageInfo(int logpos)
{
    wxArrayString * Ret = new wxArrayString();
    mutex->Lock();
    Ret->Add(Messages->Item(logpos).Sender);
    Ret->Add(ChannelName);
    Ret->Add(Messages->Item(logpos).Time);
    Ret->Add(Messages->Item(logpos).Text);
    mutex->Unlock();
    return Ret;
}

wxString * ChannelLog::GetString()
{
    wxString * Ret = new wxString(ChannelName);
    return Ret;
}

wxString * ChannelLog::GetMessageString(int logpos)
{
    wxString * Ret;
    mutex->Lock();
    Ret = Messages->Item(logpos).GetString();
    mutex->Unlock();
    return Ret;
}

wxArrayString * ChannelLog::GetListBoxArray()
{
    wxArrayString * Ret = new wxArrayString();
    wxString * add;
    mutex->Lock();
    int len = Messages->GetCount();
    for(int i = 0; i < len; i++)
    {
        add = Messages->Item(i).GetString();
        Ret->Add(*add);
        delete add;
    }
    mutex->Unlock();
    return Ret;
}

int ChannelLog::GetChannelId()
{
    return channelId;
}

void ChannelLog::ClearLog()
{
    mutex->Lock();
    Messages->Clear();
    mutex->Unlock();
    NewMessages = 0;
}

ChannelLog::~ChannelLog()
{
    mutex->Lock();
    delete Messages;
    mutex->Unlock();
    delete mutex;
}
    
////////ChannelLog End
////////MessageLog Begin

MessageLog::MessageLog()
{
    mutex = new wxMutex();
    Logs = new ArrayOfChannelLogs;
}

bool MessageLog::ClearLog(int pos)
{
    mutex->Lock();
    int len = Logs->GetCount();
    if(pos < len)
    {
        if(Logs->Item(pos).GetChannelId() != 0 || *(Logs->Item(pos).GetString()) == "Default") //If it is a channel save it, because these have to be specially opened
        {
            Logs->Item(pos).ClearLog();
            mutex->Unlock();
            return false; //Dont remove from list
        } else { //Else wise it is not so lucky
            Logs->RemoveAt(pos);
            mutex->Unlock();
            return true; //Bye Bye
        }
    }
}

//void MessageLog::ClearAllLogs()
//{
//    mutex->Lock();
//    Logs->Clear();
//    mutex->Unlock();
//}

MessageLog::AddMessageStruct * MessageLog::AddMessage(wxString * sender, wxString * text, int channelid, int type)
{
    AddMessageStruct * Ret = new AddMessageStruct;
    wxString * MessageString;
    wxString * ChannelName = new wxString;
    if(type == 0x01 || type == 0x02 || type == 0x03) //say, whisper, yell
    {
        *ChannelName = "Default";
    }
    if(type == 0x04 || type == 0x09 || type == 0x0B || type == 0x0C) //private messages
    {
        *ChannelName = *sender;
    }
    if(type == 0x05 || type == 0x0A || type == 0x0D) //channel messages
    {
    }
    int len;
    mutex->Lock();
    len = Logs->GetCount();
    bool found = false;
    for(int i = 0; i < len; i++)
    {
        if(channelid == 0) //find by name
        {
            if(*(Logs->Item(i).GetString()) == *ChannelName)
            {
                found = true;
                MessageString = Logs->Item(i).AddMessage(sender, text, type);
                Ret->ChannelName = 0; //If we dont create a new channel this will be 0
                Ret->Channel = i;
                delete ChannelName;
                break;
            }
        } else { //find by channel id
            if(Logs->Item(i).GetChannelId() == channelid)
            {
                found = true;
                MessageString = Logs->Item(i).AddMessage(sender, text, type);
                Ret->ChannelName = 0; //If we done create a new channel this will be 0
                Ret->Channel = i;
                delete ChannelName;
                break;
            }
        }
    }
    if(!found && channelid == 0) //channels must be created specially to retrieve their names
    {
        ChannelLog * NewChannel = new ChannelLog(ChannelName, 0);
        MessageString = NewChannel->AddMessage(sender, text, type);
        Logs->Add(NewChannel);
        Ret->ChannelName = ChannelName; //If we do create a new channel we need to return its name
        Ret->Channel = len;
    }
    mutex->Unlock();
    Ret->MessageString = MessageString;
    return Ret;
}

wxString * MessageLog::OpenChannel(wxString * ChannelName, int channelid)
{
    ChannelLog * NewChannel = new ChannelLog(ChannelName, channelid);
    mutex->Lock();
    Logs->Add(NewChannel);
    mutex->Unlock();
    return ChannelName;
}
    

wxArrayString * MessageLog::GetListBoxArray()
{
    wxArrayString * Ret = new wxArrayString;
    wxString * add;
    mutex->Lock();
    int len = Logs->GetCount();
    for(int i = 0; i < len; i++)
    {
        add = Logs->Item(i).GetString();
        Ret->Add(*add);
        delete add;
    }
    mutex->Unlock();
    return Ret;
}

wxArrayString * MessageLog::GetMessageBoxArray(int pos)
{
    wxArrayString * Ret;
    mutex->Lock();
    int len = Logs->GetCount();
    if(pos < len)
    {
        Ret = Logs->Item(pos).GetListBoxArray();
    }
    mutex->Unlock();
    return Ret;
}

wxArrayString * MessageLog::GetMessageInfo(int channelpos, int logpos)
{
    wxArrayString * Ret = 0;
    mutex->Lock();
    int len = Logs->GetCount();
    if(channelpos < len)
    {
        Ret = Logs->Item(channelpos).GetMessageInfo(logpos);
    }
    mutex->Unlock();
    return Ret;
}

int MessageLog::GetCount()
{
    int ret;
    mutex->Lock();
    ret = Logs->GetCount();
    mutex->Unlock();
    return ret;
}

MessageLog::~MessageLog()
{
    mutex->Lock();
    delete Logs;
    mutex->Unlock();
    delete mutex;
}
